﻿using System;
using ShureValidation.Language;

namespace ShureValidation.Rules
{
    /// <summary>
    /// Checks whether a field have been specified or not.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Language file items:
    /// <list type="table">
    ///     <listheader>
    ///         <term>ItemName</term>
    ///         <description>Language text</description>
    ///     </listheader>
    ///     <item>
    ///         <term>Required</term>
    ///         <description>'{0}' is required.</description>
    ///     </item>
    /// </list>
    /// </para>
    /// </remarks>
    [LanguagePrompt("Required", "'{0}' is required.")]
    [Serializable]
    public class RequiredRule : IRule
    {
        private readonly RequiredFlags _flags;

        /// <summary>
        /// Initializes a new instance of the <see cref="RequiredRule"/> class.
        /// </summary>
        public RequiredRule()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="RequiredRule"/> class.
        /// </summary>
        /// <param name="flags">The flags.</param>
        public RequiredRule(RequiredFlags flags)
        {
            _flags = flags;
        }

        #region IRule Members

        /// <summary>
        /// Validate a field value
        /// </summary>
        /// <param name="value">Value to validate</param>
        /// <returns><c>true</c> if validation was successful; otherwise <c>false</c>.</returns>
        public bool Validate(object value)
        {
            if (value == null)
                return false;

            var temp = value as string;
            if (temp == string.Empty)
                return (_flags & RequiredFlags.AcceptEmptyString) != 0;

            return !ValueChecker.IsEmpty(value);
        }

        /// <summary>
        /// Format an error message
        /// </summary>
        /// <param name="fieldName">Field (have already been translated)</param>
        /// <param name="rulesLanguage">Language prompts for validation rules</param>
        /// <returns>Error message formatted for the current language.</returns>
        public string Format(string fieldName, IModelLanguage rulesLanguage)
        {
            return string.Format(rulesLanguage["Required"], fieldName);
        }

        /// <summary>
        /// Checks if this rule support values of the specified format.
        /// </summary>
        /// <param name="type">Type of value</param>
        /// <returns><c>true</c> if the specified type can be validated; otherwise <c>false</c>.</returns>
        public bool SupportsType(Type type)
        {
            return true;
        }

        #endregion
    }

    /// <summary>
    /// Flags used in the required rule
    /// </summary>
    [Flags]
    public enum RequiredFlags
    {
        AcceptEmptyString
    }
}